#include "actionkill.h"
#include <Windows.h>
#include <TlHelp32.h>

ActionKill::ActionKill()
{
    classname = __FUNCTION__;
    actParam = QJsonObject();
}

ActionKill::ActionKill(QString exeName, bool killAll)
{
    classname = __FUNCTION__;
    actParam = QJsonObject();
    actParam.insert("type","name");
    actParam.insert("exe",exeName);
    actParam.insert("all",killAll?1:0);
}

ActionKill::ActionKill(int pid)
{
    actParam = QJsonObject();
    actParam.insert("type","pid");
    actParam.insert("pid",pid);
}

ExecuteRet ActionKill::execute()
{
    QString type = actParam.value("type").toString();
    if(type == "name")
    {
        //如果killall，失败一个即失败.
        //如果不是killall，成功一个即成功.
        bool succFlag = true; //如果killall，失败一个即失败.
        bool failFlag = true; //不是killall，成功一个即成功.
        QString exeName = actParam.value("exe").toString();
        bool killAll = (actParam.value("all").toInt(1)==1);
        exeName += ".exe";
        qInfo()<<classname<<"kill"<<exeName<<"isAll:"<<killAll;

        HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
        if(hSnapShot == INVALID_HANDLE_VALUE) return ERError;
        PROCESSENTRY32 procInfo;
        memset(&procInfo,0,sizeof(PROCESSENTRY32));
        procInfo.dwSize=sizeof(PROCESSENTRY32);
        while(Process32Next(hSnapShot,&procInfo)!=FALSE)
        {
            if(QString::fromWCharArray(procInfo.szExeFile).endsWith(exeName,Qt::CaseInsensitive))
            {
                if(GetCurrentProcessId() == procInfo.th32ProcessID)
                {
                    qInfo()<<"kill skip self.";
                    continue;
                }
                HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,procInfo.th32ProcessID);
                if(hProcess != NULL)
                {
                    qInfo()<<"kill "<<QString::fromWCharArray(procInfo.szExeFile);
                    bool ret = (TRUE == TerminateProcess(hProcess,0));
                    if(ret){
                        failFlag = false;
                    }
                    else{
                        succFlag = false;
                    }

                    CloseHandle(hProcess);
                    if(killAll == false) break;
                }
                else
                {
                    succFlag = false;
                }
            }
        }
        CloseHandle(hSnapShot);
        if(killAll){
            return succFlag?ERSucc:ERError;
        }
        else{
            return failFlag?ERError:ERSucc;
        }
    }
    if(type == "pid")
    {
        bool succFlag = true;
        int pid = actParam.value("pid").toInt();
        DWORD dwPid = (DWORD)pid;
        qInfo()<<classname<<"kill pid:"<<QString::number(dwPid);
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPid);
        if(hProcess != NULL)
        {
            succFlag = (TRUE == TerminateProcess(hProcess,0));
            CloseHandle(hProcess);
            return succFlag?ERSucc:ERError;
        }
        message = "open process failed";
        return ERError;
    }
    message = "illegal action kill type";
    return ERError;
}
